package com.hst.web.base.service;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.hst.core.ServiceContext;
import com.hst.core.dao.IORDao;
import com.hst.core.dao.ISQLDao;
import com.hst.core.dao.ORQuery;
import com.hst.core.dao.ORQuery.Op;
import com.hst.core.json.JsonUtil;
import com.hst.web.auth.po.User;
import com.hst.web.base.entity.TCompanyEmployee;
import com.hst.web.base.entity.TFlowConfig;
import com.hst.web.base.entity.TFlowConfigDetail;
import com.hst.web.base.entity.TFlowHistory;
import com.hst.web.base.entity.TFlowTask;
import com.hst.web.base.entity.TReivewHistory;
import com.hst.web.base.entity.TYearCheck;
import com.hst.web.base.ui.CompanyEmployee;
import com.hst.web.base.ui.PersonCardApprove;
import com.hst.web.base.ui.PersonCardQuery;
import com.hst.web.common.utils.DateTimeUtil;
import com.hst.web.sys.entity.TRole;

@Service
@Transactional
public class PersonCardService {
	
	@Autowired
	IORDao dao;
	
	@Autowired
	ISQLDao sql;
	
	@Autowired
	UserRoleService us;
	
	/**
	 * 退回申请
	 * @param approve
	 * @throws IOException 
	 * @throws JsonMappingException 
	 * @throws JsonGenerationException 
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public void back(PersonCardApprove approve,String remark,Model m) throws JsonGenerationException, JsonMappingException, IOException{
		TFlowTask task = dao.get(TFlowTask.class, approve.getId());
		User u = (User) ServiceContext.getInstance().getUser();
		
		String next = task.getNext();	//取得当前处理人角色,用户需要有这个角色才能审批
		if (us.isExistRole(u.getId(), next)) {		//如果用户存在审批角色,则允许审批
			TFlowHistory history = new TFlowHistory();
			history.setAction("back");
			history.setStatus(task.getStatus());
			history.setTaskId(task.getId());
			history.setUserid(u.getId());
			history.setRole(task.getNext());		//保存当前处理人角色
			history.setRemark(remark);
			history.setDt(new Timestamp(new Date().getTime()));
			dao.save(history);
			
			task.setNext(null);
			task.setStatus("退回");
			dao.save(task);
			
			approve.setNext(null);
			approve.setStatus("退回");
			
			String employeeCode = approve.getDataId();
			TCompanyEmployee employee = dao.get(TCompanyEmployee.class, employeeCode);
			employee.setCheckStatus("3");
			employee.setPushflag("0");
			dao.update(employee);
		}
		
		m.addAttribute("approve",JsonUtil.toString(approve));
		m.addAttribute("success","success");
	}
	
	/**
	 * 审批通过选择下一处理人
	 * @param approve
	 * @param m
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws IOException 
	 * @throws JsonMappingException 
	 * @throws JsonGenerationException 
	 */
	public void pass(PersonCardApprove approve,Model m,String remark) throws JsonGenerationException, JsonMappingException, IOException {
		TFlowTask task = dao.get(TFlowTask.class, approve.getId());
		User u = (User) ServiceContext.getInstance().getUser();
		
		String next = task.getNext();	//取得当前处理人角色,用户需要有这个角色才能审批
		if (us.isExistRole(u.getId(), next)) {		//如果用户存在审批角色,则允许审批
			TFlowHistory history = new TFlowHistory();
			history.setAction("pass");
			history.setTaskId(task.getId());
			history.setUserid(u.getId());
			history.setRole(task.getNext());		//保存当前处理人角色
			history.setRemark(remark);
			history.setStatus(task.getStatus());
			history.setDt(new Timestamp(new Date().getTime()));
			dao.save(history);
			
			List<ORQuery> querys = new ArrayList<ORQuery>();
			querys.add(new ORQuery(Op.eq,"configId",task.getConfigId()));
			querys.add(new ORQuery(Op.gt,"srl",task.getSrl()));
			querys.add(new ORQuery(Op.order,"srl","asc"));
			List<TFlowConfigDetail> details = dao.list(TFlowConfigDetail.class,querys);
			if(details.size() > 0) { //有下一步处理角色
				TFlowConfigDetail detail = details.get(0);
				task.setNext(detail.getRole());
				task.setStatus(detail.getNodeName());
				task.setSrl(detail.getSrl());
				dao.update(task);
				
				approve.setNext(detail.getRole());
				approve.setStatus(detail.getNodeName());
				approve.setSrl(detail.getSrl());
				
				//修改员工状态
				TCompanyEmployee emp = dao.get(TCompanyEmployee.class, approve.getDataId());
				if (emp != null) {
					emp.setCheckStatus("1");	//还有后续节点,状态还是待审核
					dao.update(emp);
				}
			}else {//没有下一步处理角色
				task.setNext(null);
				task.setStatus("通过");
				dao.update(task);
				
				approve.setNext(null);
				approve.setStatus("通过");
				
				//修改员工状态
				TCompanyEmployee emp = dao.get(TCompanyEmployee.class, approve.getDataId());
				if (emp != null) {
					emp.setCheckStatus("2");
					emp.setPushflag("0");
					String employeeCode = emp.getEmployeeCode();
					String cardType = approve.getCardType();
					if (StringUtils.isNotEmpty(employeeCode) && employeeCode.length() >= 8) {
						DateTimeUtil.getNextYear();
						if ("01".equals(cardType)) {	//01-长期通行证(企业人员)
							emp.setIssueNo("L" + employeeCode.substring(employeeCode.length()-8));
							emp.setBeginExpirydate(new Timestamp(new Date().getTime()));
							emp.setEndExpirydate(new Timestamp(DateTimeUtil.getNextYearLast().getTime()));
						} else {
							emp.setIssueNo("D" + employeeCode.substring(employeeCode.length()-8));
							emp.setBeginExpirydate(new Timestamp(new Date().getTime()));
							emp.setEndExpirydate(new Timestamp(DateTimeUtil.getCurrYearLast().getTime()));
						}
					}
	
					//审批通过时将复核状态变为已复核
					emp.setReviewStatus("1");		//通过
					TReivewHistory h = new TReivewHistory();
					h.setEmployeeCode(emp.getEmployeeCode());
					h.setReviewStatus(emp.getReviewStatus());
					h.setReviewType("0");	// 人员复核
					h.setRemark("通行证审批通过自动复核");
					dao.save(h);
					
					dao.update(emp);
				}
			}
		}
		m.addAttribute("approve",JsonUtil.toString(approve));
		m.addAttribute("success","success");
	}
	
	/**
	 * 员工申请通行证
	 */
	public void applyCard(String cardType,String remark,List<CompanyEmployee> emps,Model m) {
		User u = (User) ServiceContext.getInstance().getUser();
		TRole role = us.userRole(u.getId());
		List<ORQuery> querys = new ArrayList<ORQuery>();
		querys.add(new ORQuery(Op.eq,"role",role.getId()));
		querys.add(new ORQuery(Op.eq,"flowType","0"));
		List<TFlowConfig> configs = dao.list(TFlowConfig.class,querys);
		if(configs.size() > 0) {
			TFlowConfig config = configs.get(0);
			querys = new ArrayList<ORQuery>();
			querys.add(new ORQuery(Op.eq,"configId",config.getId()));
			querys.add(new ORQuery(Op.order,"srl","asc"));
			List<TFlowConfigDetail> details = dao.list(TFlowConfigDetail.class,querys);
			if(details.size() > 0) {
				TFlowConfigDetail detail = details.get(0);
				for(CompanyEmployee emp:emps) {
					TCompanyEmployee companyEmployee = dao.get(TCompanyEmployee.class, emp.getEmployeeCode());	//取得数据库中的人员状态
					String checkStatus = companyEmployee.getCheckStatus();
					if ("1".equals(checkStatus) || "2".equals(checkStatus)) {	//如果状态为待审核、审核通过,则不再允许申请
						continue;
					}
					
					TFlowTask task = new TFlowTask();
					task.setCardType(cardType);
					task.setConfigId(detail.getConfigId());
					task.setSrl(detail.getSrl());
					task.setNext(detail.getRole());
					task.setRemark(remark);
					task.setFlow("0");  //员工通行证申请
					task.setDataId(emp.getEmployeeCode());
					task.setStatus(detail.getNodeName());
					dao.save(task);
					
					TFlowHistory history = new TFlowHistory();
					history.setTaskId(task.getId());
					history.setUserid(u.getId());
					history.setRole(config.getRole());		//保存当前处理人角色(发起人角色从TFlowConfig表中取得)
					history.setAction("pass");
					history.setStatus("发起申请");
					history.setRemark(remark);
					history.setDt(new Timestamp(new Date().getTime()));
					dao.save(history);
					
					TCompanyEmployee employee = dao.get(TCompanyEmployee.class, emp.getEmployeeCode());
					employee.setCheckStatus("1");
					dao.save(employee);
				}
				m.addAttribute("success","success");
			}else {
				m.addAttribute("errorCode","error");
				m.addAttribute("msg","请先配置流程");
			}
		}else {
			m.addAttribute("errorCode","error");
			m.addAttribute("msg","请先配置流程");
		}
	}
	
	/**
	  * 审批带出历史信息
	 * @param approve
	 * @param m
	 * @throws IOException 
	 * @throws JsonMappingException 
	 * @throws JsonGenerationException 
	 */
	public void listApplyDetail(PersonCardApprove approve,Model m) throws JsonGenerationException, JsonMappingException, IOException {
		User u = (User) ServiceContext.getInstance().getUser();
		
		String next = approve.getNext();	//取得当前处理人角色,用户需要有这个角色才能审批
		if (!us.isExistRole(u.getId(), next)) {		//如果用户存在审批角色,则允许审批
			m.addAttribute("msg","当前登录人不能审批该申请");
			return;
		}
		
		String employee = approve.getDataId();
		String taskId = approve.getId();
		List<ORQuery> querys = new ArrayList<ORQuery>();
		querys.add(new ORQuery(Op.eq,"taskId",taskId));
		querys.add(new ORQuery(Op.order,"dt","asc"));
		List<TFlowHistory> historys = dao.list(TFlowHistory.class,querys);
		m.addAttribute("historys",JsonUtil.toString(historys));
		
		querys = new ArrayList<ORQuery>();
		querys.add(new ORQuery(Op.eq,"dataId",employee));
		querys.add(new ORQuery(Op.eq,"flow","0"));
		querys.add(new ORQuery(Op.neq,"id",taskId));
		querys.add(new ORQuery(Op.order,"createTime","asc"));
		List<TFlowTask> tasks = dao.list(TFlowTask.class,querys);
		m.addAttribute("tasks",JsonUtil.toString(tasks));
		
		querys = new ArrayList<ORQuery>();
		querys.add(new ORQuery(Op.eq,"dataId",employee));
		querys.add(new ORQuery(Op.eq,"flow","0"));
		querys.add(new ORQuery(Op.neq,"id",taskId));
		querys.add(new ORQuery(Op.notnull,"next",""));
		List<TFlowTask> ts = dao.list(TFlowTask.class,querys);
		m.addAttribute("numbers",ts.size());
		
		TCompanyEmployee employe = dao.get(TCompanyEmployee.class, employee);
		m.addAttribute("employee",JsonUtil.toString(employe));
	}
	
	/**
	 * 查询审批历史信息
	 * @param approve
	 * @param m
	 * @throws IOException 
	 * @throws JsonMappingException 
	 * @throws JsonGenerationException 
	 */
	public void listApplyDetailView(PersonCardApprove approve,Model m) throws JsonGenerationException, JsonMappingException, IOException {
		User u = (User) ServiceContext.getInstance().getUser();
		TRole role = us.userRole(u.getId());
		
		String employee = approve.getDataId();
		String taskId = approve.getId();
		List<ORQuery> querys = new ArrayList<ORQuery>();
		querys.add(new ORQuery(Op.eq,"taskId",taskId));
		querys.add(new ORQuery(Op.order,"dt","asc"));
		List<TFlowHistory> historys = dao.list(TFlowHistory.class,querys);
		m.addAttribute("historys",JsonUtil.toString(historys));
		
		querys = new ArrayList<ORQuery>();
		querys.add(new ORQuery(Op.eq,"dataId",employee));
		querys.add(new ORQuery(Op.eq,"flow","0"));
		querys.add(new ORQuery(Op.neq,"id",taskId));
		querys.add(new ORQuery(Op.order,"createTime","asc"));
		List<TFlowTask> tasks = dao.list(TFlowTask.class,querys);
		m.addAttribute("tasks",JsonUtil.toString(tasks));
		
		querys = new ArrayList<ORQuery>();
		querys.add(new ORQuery(Op.eq,"dataId",employee));
		querys.add(new ORQuery(Op.eq,"flow","0"));
		querys.add(new ORQuery(Op.neq,"id",taskId));
		querys.add(new ORQuery(Op.notnull,"next",""));
		List<TFlowTask> ts = dao.list(TFlowTask.class,querys);
		m.addAttribute("numbers",ts.size());
		
		TCompanyEmployee employe = dao.get(TCompanyEmployee.class, employee);
		m.addAttribute("employee",JsonUtil.toString(employe));
	}	
	
	public void backCheckStatus(List<CompanyEmployee> employees,Model m) {
		for(CompanyEmployee e:employees) {
			TCompanyEmployee employee = dao.get(TCompanyEmployee.class, e.getEmployeeCode());
			employee.setCheckStatus("0");
			dao.update(employee);
		}
		m.addAttribute("success","success");
	}
	
	/***
	 * 取得最后一条审批记录
	 * @param 
	 * @param 
	 */	
	public TFlowHistory getLastFlowHistory(PersonCardQuery personCardQuery) {
		String taskId = personCardQuery.getId();
		TFlowHistory flowHistory = null;
		List<ORQuery> querys = new ArrayList<ORQuery>();
		querys.add(new ORQuery(Op.eq,  "taskId", taskId));
		querys.add(new ORQuery(Op.order, "createTime", "desc"));
		List<TFlowHistory> listFlowHistory =  dao.list(TFlowHistory.class, querys);
		if (listFlowHistory.size() > 0) {
			flowHistory = listFlowHistory.get(0);
		}
		return flowHistory;
	}
	
	/**
	 * 员工通行证年审
	 */
	public void applyYearCheck(String cardType,String remark,List<CompanyEmployee> emps,Model m) {
		User u = (User) ServiceContext.getInstance().getUser();
		TRole role = us.userRole(u.getId());
		List<ORQuery> querys = new ArrayList<ORQuery>();

		String currMonth = DateTimeUtil.getCurrMonth();
		Date baseYearLastDate = DateTimeUtil.getCurrYearLast();
		if ("11".equals(currMonth) || "12".equals(currMonth)) {
			baseYearLastDate = DateTimeUtil.getNextYearLast();
		} else if ("1".equals(currMonth) || "2".equals(currMonth) || "3".equals(currMonth)) {
			baseYearLastDate = DateTimeUtil.getCurrYearLast();
		} else {
			baseYearLastDate = DateTimeUtil.getCurrYearLast();
		}
		
		querys = new ArrayList<ORQuery>();
		for(CompanyEmployee emp:emps) {
			TCompanyEmployee companyEmployee = dao.get(TCompanyEmployee.class, emp.getEmployeeCode());	//取得数据库中的人员状态
			
			String checkStatus = companyEmployee.getCheckStatus();
			String issueNo = companyEmployee.getIssueNo();
			Timestamp expiryDateOld = companyEmployee.getEndExpirydate();
			Timestamp endExpirydate = companyEmployee.getEndExpirydate();
			if (endExpirydate == null) {
				endExpirydate = new Timestamp(new Date().getTime());
			}
			if (StringUtils.isNotEmpty(issueNo) && !baseYearLastDate.before(endExpirydate)) {
				//companyEmployee.get
				if ("01".equals(cardType)) {	//01-长期通行证(企业人员)
					//companyEmployee.setBeginExpirydate(new Timestamp(new Date().getTime()));
					companyEmployee.setEndExpirydate(new Timestamp(DateTimeUtil.calendarAdd(baseYearLastDate, 1, 1).getTime()));
				} else {
					//companyEmployee.setBeginExpirydate(new Timestamp(new Date().getTime()));
					companyEmployee.setEndExpirydate(new Timestamp(baseYearLastDate.getTime()));
				}
				
				dao.update(companyEmployee);
				
				TYearCheck yearCheck = new TYearCheck();
				yearCheck.setEmployeeCode(emp.getEmployeeCode());
				yearCheck.setExpiryDateOld(expiryDateOld);
				yearCheck.setExpiryDateNew(companyEmployee.getEndExpirydate());
	            yearCheck.setOpType("1");
	            yearCheck.setOpTime(new Timestamp(new Date().getTime()));
	            yearCheck.setOpUserid(u.getId());
				dao.save(yearCheck);
			}
		}
		m.addAttribute("success","success");
	}	
}
